using System;
using EnvDTE;

namespace NUnitGenAddIn.Core.Test
{
    /// <summary>
    /// Mock File Code Model
    /// </summary>
	public class MockFileCodeModel : FileCodeModel
	{
		private readonly MockCodeElements _codeElements;

        /// <summary>
        /// Initializes a new instance of the <see cref="MockFileCodeModel"/> class.
        /// </summary>
        /// <param name="codeElements">The code elements.</param>
		public MockFileCodeModel(MockCodeElements codeElements)
		{
			_codeElements = codeElements;
		}

		#region FileCodeModel Members

        /// <summary>
        /// Adds the attribute.
        /// </summary>
        /// <param name="name">The name.</param>
        /// <param name="value">The value.</param>
        /// <param name="position">The position.</param>
        /// <returns></returns>
		public CodeAttribute AddAttribute(string name, string value, object position)
		{
			throw new Exception("The method or operation is not implemented.");
		}

        /// <summary>
        /// Adds the class.
        /// </summary>
        /// <param name="name">The name.</param>
        /// <param name="position">The position.</param>
        /// <param name="bases">The bases.</param>
        /// <param name="implementedInterfaces">The implemented interfaces.</param>
        /// <param name="access">The access.</param>
        /// <returns></returns>
		public CodeClass AddClass(string name, object position, object bases, object implementedInterfaces, vsCMAccess access)
		{
			throw new Exception("The method or operation is not implemented.");
		}

        /// <summary>
        /// Adds the delegate.
        /// </summary>
        /// <param name="name">The name.</param>
        /// <param name="type">The type.</param>
        /// <param name="position">The position.</param>
        /// <param name="access">The access.</param>
        /// <returns></returns>
		public CodeDelegate AddDelegate(string name, object type, object position, vsCMAccess access)
		{
			throw new Exception("The method or operation is not implemented.");
		}

        /// <summary>
        /// Adds the enum.
        /// </summary>
        /// <param name="name">The name.</param>
        /// <param name="position">The position.</param>
        /// <param name="bases">The bases.</param>
        /// <param name="access">The access.</param>
        /// <returns></returns>
		public CodeEnum AddEnum(string name, object position, object bases, vsCMAccess access)
		{
			throw new Exception("The method or operation is not implemented.");
		}

        /// <summary>
        /// Adds the function.
        /// </summary>
        /// <param name="name">The name.</param>
        /// <param name="kind">The kind.</param>
        /// <param name="type">The type.</param>
        /// <param name="position">The position.</param>
        /// <param name="access">The access.</param>
        /// <returns></returns>
		public CodeFunction AddFunction(string name, vsCMFunction kind, object type, object position, vsCMAccess access)
		{
			throw new Exception("The method or operation is not implemented.");
		}

        /// <summary>
        /// Adds the interface.
        /// </summary>
        /// <param name="name">The name.</param>
        /// <param name="position">The position.</param>
        /// <param name="bases">The bases.</param>
        /// <param name="access">The access.</param>
        /// <returns></returns>
		public CodeInterface AddInterface(string name, object position, object bases, vsCMAccess access)
		{
			throw new Exception("The method or operation is not implemented.");
		}

        /// <summary>
        /// Adds the <c>Namespace</c>.
        /// </summary>
        /// <param name="name">The name.</param>
        /// <param name="position">The position.</param>
        /// <returns></returns>
		public CodeNamespace AddNamespace(string name, object position)
		{
			throw new Exception("The method or operation is not implemented.");
		}

        /// <summary>
        /// Adds the structure.
        /// </summary>
        /// <param name="name">The name.</param>
        /// <param name="position">The position.</param>
        /// <param name="bases">The bases.</param>
        /// <param name="implementedInterfaces">The implemented interfaces.</param>
        /// <param name="access">The access.</param>
        /// <returns></returns>
		public CodeStruct AddStruct(string name, object position, object bases, object implementedInterfaces,
		                            vsCMAccess access)
		{
			throw new Exception("The method or operation is not implemented.");
		}

        /// <summary>
        /// Adds the variable.
        /// </summary>
        /// <param name="name">The name.</param>
        /// <param name="type">The type.</param>
        /// <param name="position">The position.</param>
        /// <param name="access">The access.</param>
        /// <returns></returns>
		public CodeVariable AddVariable(string name, object type, object position, vsCMAccess access)
		{
			throw new Exception("The method or operation is not implemented.");
		}

        /// <summary>
        /// Codes the element from point.
        /// </summary>
        /// <param name="point">The point.</param>
        /// <param name="scope">The scope.</param>
        /// <returns><see cref="CodeElement"/> object</returns>
		public virtual CodeElement CodeElementFromPoint(TextPoint point, vsCMElement scope)
		{
			return CodeElementFromPoint(point, _codeElements);
		}

        /// <summary>
        /// Codes the element from point.
        /// </summary>
        /// <param name="point">The point.</param>
        /// <param name="codeElements">The code elements.</param>
        /// <returns></returns>
		private static CodeElement CodeElementFromPoint(TextPoint point, CodeElements codeElements)
		{
			foreach (MockCodeElement e in codeElements)
			{
			    if (e.StartPoint.Line == point.Line)
			    {
			        return e;
			    }
			
                if (e.MockChildren.Count > 0)
                {
                    return CodeElementFromPoint(point, e.MockChildren);
                }
			}

		    return null;
		}

        /// <summary>
        /// Gets the code elements.
        /// </summary>
        /// <value>The code elements.</value>
		public CodeElements CodeElements
		{
			get { return _codeElements; }
		}

        /// <summary>
        /// Gets the DTE.
        /// </summary>
        /// <value>The DTE.</value>
		public DTE DTE
		{
			get { throw new Exception("The method or operation is not implemented."); }
		}

        /// <summary>
        /// Gets the language.
        /// </summary>
        /// <value>The language.</value>
		public string Language
		{
			get { throw new Exception("The method or operation is not implemented."); }
		}

        /// <summary>
        /// Gets the parent.
        /// </summary>
        /// <value>The parent.</value>
		public ProjectItem Parent
		{
			get { throw new Exception("The method or operation is not implemented."); }
		}

        /// <summary>
        /// Removes the specified element.
        /// </summary>
        /// <param name="element">The element.</param>
		public void Remove(object element)
		{
			throw new Exception("The method or operation is not implemented.");
		}

		#endregion
	}
}